package net.csdn.business.common.domain.request;

import com.google.common.collect.Lists;
import lombok.Data;
import net.csdn.business.common.constant.CommonConstants;
import net.csdn.business.common.domain.common.ConditionQueryDto;
import net.csdn.business.common.domain.validation.groups.System;
import net.csdn.business.common.enums.IssueEnum;
import net.csdn.business.common.utils.HtmlParserTextUtil;
import net.csdn.business.common.utils.ValidatorUtil;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.List;

/**
 * @author likun
 * @date 2022/7/5 17:24
 */
@Data
public class IssueBaseQueryDto implements Serializable {
    public static final String NO_LABEL = "no";
    /**
     * 当前登录用户
     */
    @NotBlank(message = "uid 不合法", groups = {System.class})
    private String uid;

    @Length(max = 50, message = "keyword 不能超过50个字符")
    private String keyword;

    private String order = IssueEnum.OrderByEnum.RECENTLY_UPDATE.getCode();

    @Range(min = 1, max = 2, message = "status 不合法")
    private Integer status;

    @Range(min = 1, max = 100, message = "pageNum 不合法")
    private int pageNum = 1;

    @Range(min = 1, max = 1000, message = "pageSize 不合法")
    private int pageSize = 10;

    /**
     * {@link IssueEnum.QueryTypeEnum}
     */
    private String filter;

    /**
     * 标签
     */
    // @Size(min = 24, max = 24, message = "labelId 不合法")
    private String labelId;

    @Size(min = 24, max = 24, message = "milepostId 不合法")
    private String milepostId;


    public static <T extends IssueBaseQueryDto> ConditionQueryDto queryCommonCondition(T dto) {
        boolean join = false;
        List<ConditionQueryDto.Filter> filters = Lists.newArrayList();
        if (StringUtils.isNotBlank(dto.getLabelId())) {
            if (NO_LABEL.equalsIgnoreCase(dto.getLabelId())) {
                filters.add(new ConditionQueryDto.Filter("label", Lists.newArrayList(IssueEnum.LabelEnum.NO.getCode().toString())));
            } else {
                ValidatorUtil.builder().checkStringLen(dto.getLabelId(), 24, 24, "label_id");
                filters.add(new ConditionQueryDto.Filter("label_id", Lists.newArrayList(dto.getLabelId())));
                join = true;
            }
        }

        if (StringUtils.isNotBlank(dto.getMilepostId())) {
            filters.add(new ConditionQueryDto.Filter("milepost_id", Lists.newArrayList(dto.getMilepostId())));
        }

        if (StringUtils.isNotBlank(dto.getKeyword())) {
            filters.add(new ConditionQueryDto.Filter("title", Lists.newArrayList(HtmlParserTextUtil.clearHtml(dto.getKeyword())), ConditionQueryDto.LIKE));
        }

        if (StringUtils.isNotBlank(dto.getFilter())) {
            String[] fs = StringUtils.split(dto.getFilter(), CommonConstants.COMMA);
            // 支持 filter=k1:v1,k2:v2 忽略 uid
            int fsLen = fs.length;
            if (StringUtils.contains(dto.getFilter(), CommonConstants.COLON) || fsLen > CommonConstants.INT_ONE) {
                for (String f : fs) {
                    String[] kv = StringUtils.split(f, CommonConstants.COLON);
                    IssueEnum.QueryTypeEnum queryTypeEnum = IssueEnum.QueryTypeEnum.ofCode(kv[CommonConstants.INT_ZERO]);
                    filters.add(new ConditionQueryDto.Filter(queryTypeEnum.getField(), Lists.newArrayList(kv[CommonConstants.INT_ONE])));
                }
            } else {
                IssueEnum.QueryTypeEnum queryTypeEnum = IssueEnum.QueryTypeEnum.ofCode(dto.getFilter());
                filters.add(new ConditionQueryDto.Filter(queryTypeEnum.getField(), Lists.newArrayList(dto.getUid())));
            }
        }

        return new ConditionQueryDto(
                null,
                filters,
                dto.getPageNum(),
                dto.getPageSize(),
                true,
                join
        );
    }

    public static void wrapperStatus(final ConditionQueryDto query, IssueBaseQueryDto dto) {
        if (null == dto.getStatus()) {
            return;
        }
        query.getFilters().add(new ConditionQueryDto.Filter("status", Lists.newArrayList(dto.getStatus().toString())));
    }

    public static ConditionQueryDto.Order order(IssueBaseQueryDto dto) throws IllegalArgumentException {
        IssueEnum.OrderByEnum orderByEnum = IssueEnum.OrderByEnum.ofCode(dto.getOrder());
        return new ConditionQueryDto.Order(orderByEnum.getField(), orderByEnum.getOrder());
    }
}